const { isDevelopment, isProduction } = require('./env')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const { PROJECT_PATH } = require('../constant')
const WebpackBar = require('webpackbar')
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin')
const CopyWebpackPlugin = require('copy-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin')

// 因为后续要配sass和less也需要使用到这套规则，所以这里抽离出来
const getCssLoaders = () => {
    const cssLoaders = [
        isDevelopment ? 'style-loader' : MiniCssExtractPlugin.loader,
        {
            loader: 'css-loader',
            options: {
                modules: {
                    localIdentName: "[local]--[hash:base64:5]"
                },
                sourceMap: isDevelopment,
            }
        }
    ]

    // 开发环境一般用chrom不会有问题，防止开发环境下看样式有一堆前缀影响查看，因此只在生产环境使用
    isProduction && cssLoaders.push({
        loader: 'postcss-loader',
        options: {
            postcssOptions: {
                plugins: [
                    isProduction && [
                        'postcss-preset-env',
                        {
                            autoprefixer: {
                                grid: true
                            }
                        }
                    ],
                    // new CleanWebpackPlugin(),
                ]
            }
        }
    })

    return cssLoaders
}

module.exports = {
    entry: {
        app: path.resolve(PROJECT_PATH, './src/index.tsx')
    },
    plugins: [
        new HtmlWebpackPlugin({
            template: path.resolve(PROJECT_PATH, './public/index.html'),
        }),
        new WebpackBar({
            name: 'Link Startou!!!',
            color: '#52c41a'
        }),
        new ForkTsCheckerWebpackPlugin({
            typescript: {
                configFile: path.resolve(PROJECT_PATH, './tsconfig.json'),
            },
        }), 
        // new CopyWebpackPlugin([
        //     {
        //         context: 'public',
        //         from:'*',
        //         to: path.resolve(PROJECT_PATH, './dist/public'),
        //         toType: 'dir',
        //     },
        // ],{
        //     ignore: ['**/index.html',{dot: true}]// **表示任意目录下
        // })
        new CopyWebpackPlugin({
            patterns: [
                {
                    // noErrorOnMissing: true,// true 的时候build不会报错，但是也不会copy
                    // context: 'public',  from: '*', // C:/code/blue/public/*'
                    // context: 'public',  from: '/',  //   C:/**/*'
                    // context: '',  from: 'public', //C:/code/blue/public/*
                    // context: 'public',  from: './', //C:/code/blue/public/**/*'
                    // context: 'public',  from: 'index.html', // 文件路径正确了，但是文件名也被当做路径了
                    // context: 'public',from:'./script', // C:/code/blue/public/script 报错
                    // context: 'public',  from: 'index',// 报错，不复制
                    // from:path.resolve(PROJECT_PATH, './public/'),// C:/code/blue/public/**/*
                    // from: path.resolve(PROJECT_PATH, '*'),// 报错 C:\code\blue\*
                    // from: path.resolve(PROJECT_PATH, 'public/*'),
                    // from: path.resolve(PROJECT_PATH, '/'), // 报错
                    // from: path.resolve(PROJECT_PATH, './public'), // 报错 C:/code/blue/public/**/*'
                    // from: 'public/*',// 报错C:/code/blue/public/*
                    // from:'./public/', // 报错'C:/code/blue/public/**/*
                    from:'public',
                    to: path.resolve(PROJECT_PATH, './dist/public'),
                    toType: 'dir',
                    globOptions: {
                        dot: true,
                        gitignore: true,
                        // ignore: ['**/index.html'],		// **表示任意目录下
                    },
                },
            ],
        
        })
    ],
    //配置webpack如何寻找模块对应的文件
    resolve: {
        alias: {
            'src': path.resolve(PROJECT_PATH, './src'),
            'components': path.resolve(PROJECT_PATH, './src/components'),
            'utils': path.resolve(PROJECT_PATH, './src/utils'),
        },
        extensions: ['.tsx', '.ts', '.js', '.json'],//在导入语句没带文件后缀时，webpack会自动带上后缀去尝试访问文件是否存在，extensions用于配置在尝试过程中用到的后缀列表，webpack 会按照定义的后缀名的顺序依次处理文件，在配置时尽量把最常用到的后缀放到最前面，可以缩短查找时间
    },
    module: {
        rules: [
            {
                test: /\.(tsx?|js)$/,
                loader: 'babel-loader',
                options: { cacheDirectory: true }, // babel-loader 在执行的时候，可能会产生一些运行期间重复的公共文件，造成代码体积大冗余，同时也会减慢编译效率，所以开启该配置将这些公共文件缓存起来，下次编译就会加快很多
                exclude: /node_modules/,// 第三方包不需要进行转译，排除后可加快打包速度
            },
            {
                test: /\.css$/,
                use: [...getCssLoaders()]
            },
            {
                test: /\.less$/,
                use: [
                    ...getCssLoaders(),
                    {
                        loader: 'less-loader',
                        options: {
                            sourceMap: isDevelopment,
                        }
                    }
                ]
            },
            {
                test: /\.scss$/,
                use: [
                    ...getCssLoaders(),
                    {
                        loader: 'sass-loader',
                        options: {
                            sourceMap: isDevelopment,
                        }
                    }
                ]
            },
            {
                test: [/\.bmp$/, /\.gif$/, /\.jpe?g$/, /\.png$/],
                type: 'asset',
                parser: {
                    dataUrlCondition: {
                        maxSize: 4 * 1024,
                    },
                },
            },
            {
                test: /\.(eot|svg|ttf|woff|woff2?)$/,
                type: 'asset/resource',
            },
        ]
    },
    // 开启编译缓存，提高二次编译速度
    cache: {
        type: 'filesystem',
        buildDependencies: {
          config: [__filename],
        },
      },
}